//
//  vhiCVBleManager.m
//  vhMedicalServices
//
//  Created by moon_zm on 2025/5/16.
//

//弱引用（__weak）为延长对象生命周期与 ZMStrong()成对使用
#define iCVBLEWeak( x ) \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
autoreleasepool{} __weak __typeof__(x) __weak_##x##__ = x; \
_Pragma("clang diagnostic pop")
//强引用（__strong）为延长对象生命周期与 ZMWeak()成对使用
#define iCVBLEStrong( x ) \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
autoreleasepool{} __typeof__(x) x = __weak_##x##__; if (!x)return;\
_Pragma("clang diagnostic pop")

#import "vhiCVBLEManager.h"
#import "vhECGFiltersLib.h"
#import "vhECGStressTempLib.h"

@interface vhiCVBleManager ()<NSAVHCVScanDelegate, vhECGiCV200BleDelegate>
{
//    NSAVHCVDevice *targetDevice;
    BOOL collecting;
    BOOL isAutoCollect;
}

@property (nonatomic, assign) int rate;//采样率
@property (nonatomic, copy) NSString * _Nullable deviceId;
@property (nonatomic, assign) int batVol;
@property (nonatomic, strong) NSDate *last_found_date;
@property (nonatomic, strong) CBPeripheral *peripheral;
@property (nonatomic, assign) double uVpb;//default is 1.0
@property (nonatomic, assign) BOOL isReady;
@property (nonatomic, assign) BOOL collecting;

@property (nonatomic, strong) NSAVHCVScan *scanner;
@property (nonatomic, strong) NSAVHCVConnect *connecter;
@end
@implementation vhiCVBleManager
@synthesize peripheral;
@synthesize last_found_date;
@synthesize rate;
@synthesize batVol;
@synthesize deviceId;
@synthesize uVpb;
@synthesize isReady;
@synthesize collecting;

+ (instancetype)shared {
    static vhiCVBleManager *identifier = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        identifier = [[vhiCVBleManager alloc] init];
    });
    return identifier;;
}

- (instancetype)init {
    if (self = [super init]) {
        self.rate = 500;
        self.uVpb = 1.0;
        self.collecting = NO;
    }
    return self;
}

- (NSAVHCVScan *)scanner {
    if (!_scanner){
        _scanner = [[NSAVHCVScan alloc] init];
        _scanner.bluetooth_off_handler = ^{
            //call back here when iOS bluetooth OFF.
        };
        _scanner.unauthorized_handler = ^{
            //call back here when Not allow Bluetooth by User.
        };
        _scanner.unsupport_handler = ^{
            //call back only older iOS device.
        };
        _scanner.delegate = self;
    }
    return _scanner;
}

- (NSAVHCVConnect *)connecter {
    if (!_connecter) {
        _connecter = [[NSAVHCVConnect alloc] init];
        _connecter.delegate = self;
        _connecter.manager = self.scanner.manager;
        _connecter.currentQueue = self.scanner.currentQueue;
    }
    return _connecter;
}

- (void)startScan {
    if (!self.scanner.scaning) {
        [self.scanner start_scan];
    }
}

- (void)stopScan {
    if (self.scanner.scaning) {
        [self.scanner stop_scan];        
    }
}

-(BOOL)connect:(NSString *)deviceName isAutoCollect:(BOOL)isAuto {
    isAutoCollect = isAuto;
    NSAVHCVDevice *targetDevice = [self.scanner getAVHCVDeviceWithName:deviceName];
    if (!targetDevice) {
        if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:connectingStatus:)]) {
            [self.delegate icvBleManager:self connectingStatus:vhiCVBleConnectStatus_LostDevice];
        }
        NSLog(@"Lost device.");
        return NO;
    }
    
    __weak typeof(self) weakSelf = self;
    BOOL success = [self.connecter connect:targetDevice withHandler:^{
        __strong __typeof(weakSelf)strongSelf = weakSelf;
        strongSelf.rate = strongSelf.connecter.current_device.rate;
        strongSelf.deviceId = strongSelf.connecter.current_device.deviceId;
        strongSelf.batVol = strongSelf.connecter.current_device.batVol;
        strongSelf.last_found_date = strongSelf.connecter.current_device.last_found_date;
        strongSelf.peripheral = strongSelf.connecter.current_device.peripheral;
        strongSelf.uVpb = strongSelf.connecter.current_device.uVpb;
        strongSelf.isReady = strongSelf.connecter.current_device.isReady;
        if (strongSelf.delegate && [strongSelf.delegate respondsToSelector:@selector(icvBleManager:connectingStatus:)]) {
            [strongSelf.delegate icvBleManager:strongSelf connectingStatus:vhiCVBleConnectStatus_Connected];
        }
        if (isAuto) {
            [strongSelf performSelector:@selector(collectStart) withObject:nil afterDelay:0.2];
        }
//        if (self.scanner.scaning) {
//            [self.scanner stop_scan];
//        }
    } withProgressHandler:^(NSAVHCVConnecting_Status status) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;

        vhiCVBleConnectStatus type = vhiCVBleConnectStatus_Connecting;
        switch (status) {
            case NSAVHCVConnecting_Status_Connecting:
                type = vhiCVBleConnectStatus_Connecting;
                NSLog(@"Connecting status.");
                break;
            case NSAVHCVConnecting_Status_DiscoverCharacteristics:
                type = vhiCVBleConnectStatus_DiscoverCharacteristics;
                NSLog(@"Discover Characteristics.");
                break;
            case NSAVHCVConnecting_Status_BuildCredits:
                type = vhiCVBleConnectStatus_BuildCredits;
                NSLog(@"Build Credits.");
                break;
            case NSAVHCVConnecting_Status_InitDevice:
                type = vhiCVBleConnectStatus_InitDevice;
                NSLog(@"Init device.");
                break;
            case NSAVHCVConnecting_Status_InitDeviceAgain:
                type = vhiCVBleConnectStatus_InitDeviceAgain;
                NSLog(@"Re init device.");
                break;
            default:
                break;
        }
        if (strongSelf.delegate && [strongSelf.delegate respondsToSelector:@selector(icvBleManager:connectingStatus:)]) {
            [strongSelf.delegate icvBleManager:strongSelf connectingStatus:type];
        }
    } withDisConnectHandler:^(NSError * _Nullable error) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;
        if (strongSelf.delegate && [strongSelf.delegate respondsToSelector:@selector(icvBleManager:connectingStatus:)]) {
            if (error) {
                [strongSelf.delegate icvBleManager:strongSelf connectingStatus:vhiCVBleConnectStatus_DisconnectedError];
                NSLog(@"Connect With Error:%@",[error description]);
            }else {
                [strongSelf.delegate icvBleManager:strongSelf connectingStatus:vhiCVBleConnectStatus_Disconnected];
            }
        }
        // Something code for reConnect the device.
        
    }];
    
    if (NO == success){
        NSLog(@"connect divece failed.");
        NSLog(@"delegate, manager, currentQueue can't be nil.");
        NSLog(@"other else your permission has expired.");
    }else{
        NSLog(@"connectting...");
    }
    return success;
}

- (void)disConnectWith:(vhiCVBleDisConnect_Handler)completed{
    [self collectStop];
    [self.connecter disConnectWith:completed];
}

- (void)collectStart {
    if (!self.connecter.collecting) {
        self.collecting = YES;
        [self.connecter collect_start];
    }
}

- (void)collectStop {
    if (self.connecter.collecting) {
        self.collecting = NO;
        [self.connecter collect_stop];
    }
}


#pragma mark - NSAVHCVScanDelegate -
-(void)foundDeviceName:(NSString *)name{
    if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:foundDeviceName:)]) {
        [self.delegate icvBleManager:self foundDeviceName:name];
    }
//    if (targetDevice && [targetDevice.peripheral.name isEqualToString:name]) {
//        [self connect:name isAutoCollect:isAutoCollect];
//    }
}

-(void)lostDeviceName:(NSString *)name{
    if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:lostDeviceName:)]) {
        [self.delegate icvBleManager:self lostDeviceName:name];
    }
}

#pragma mark - vhECGiCV200BleDelegate -
//是否使用二维数组数据模式
- (void)dataReceivedWithData:(NSArray <NSArray <NSNumber *>*>* _Null_unspecified)ECGs {
    if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:data:)]) {
        @iCVBLEWeak(self);
        [NSAVHCVAssemData devicesECGsAssemSingleData:ECGs handler:^(NSArray<NSNumber *> * _Nullable ecgData) {
            @iCVBLEStrong(self);
            NSArray *filters = [[vhECGFiltersLib shared] filtersLibWithData:ecgData];
            [self getHBRAndRRmsWithECGs:filters];
            [self filterECGsAssemECGsData:filters];
        }];
//        [[vhECGFiltersLib shared] filtersECGsData:ECGs dataHandler:^(NSArray<NSArray<NSNumber *> *> * _Nullable ecgData) {
//            @iCVBLEStrong(self);
//            [self.delegate icvBleManager:self data:ecgData];
//        } hbrHandler:^(int hbr) {
//            @iCVBLEStrong(self);
//            if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:heartBeatRate:)]) {
//                [self.delegate icvBleManager:self heartBeatRate:hbr];
//            }
//        } rrmsHandler:^(int rrms) {
//            @iCVBLEStrong(self);
//            if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:rrIntervalMs:)]) {
//                [self.delegate icvBleManager:self rrIntervalMs:rrms];
//            }
//        }];
    }
    
}

- (void)filterECGsAssemECGsData:(NSArray <NSNumber *>*)ECGs {
    @iCVBLEWeak(self);
    [NSAVHCVAssemData filterECGsAssemECGsData:ECGs handler:^(NSArray<NSArray<NSNumber *> *> * _Nullable ecgData) {
        @iCVBLEStrong(self);
        [self.delegate icvBleManager:self data:ecgData];
    }];
}

- (void)dataErrorDetectedWithError:(NSError * _Null_unspecified)error {
    if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:dataError:)]) {
        [self.delegate icvBleManager:self dataError:error];
    }
}

// This function is called to notify 12 lead connectivity status
- (void)leadsConnectivityStatusUpdatedWithI:(BOOL)linked_I II:(BOOL)linked_II III:(BOOL)linked_III
                                        aVR:(BOOL)linked_aVR aVL:(BOOL)linked_aVL aVF:(BOOL)linked_aVF
                                         V1:(BOOL)linked_V1 V2:(BOOL)linked_V2 V3:(BOOL)linked_V3
                                         V4:(BOOL)linked_V4 V5:(BOOL)linked_V5 V6:(BOOL)linked_V6 {
    if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:updateLeadWithI:II:III:aVR:aVL:aVF:V1:V2:V3:V4:V5:V6:)]) {
        [self.delegate icvBleManager:self updateLeadWithI:linked_I II:linked_II III:linked_III aVR:linked_aVR aVL:linked_aVL aVF:linked_aVF V1:linked_V1 V2:linked_V2 V3:linked_V3 V4:linked_V4 V5:linked_V5 V6:linked_V6];
    }
}

//iCV200BLE device battery value
- (void)deviceBattery:(int)value {
    if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:battery:)]) {
        [self.delegate icvBleManager:self battery:value];
    }
}



#pragma mark - private -
#pragma mark - HR and RR
- (void)getHBRAndRRmsWithECGs:(NSArray <NSNumber *>*)ECGs{
    if (ECGs.count < 12) return;
    NSMutableArray *target = [[NSMutableArray alloc] init];
    NSInteger i = 0;
    while (target.count < 12) {
        [target addObject:[self checkNumber:[ECGs objectAtIndex:i]]];
        i++;
    }
//    //获取心率 stress Temp lib 库处理方式
//    short data1 = [[target objectAtIndex:0] shortValue];
//    short data2 = [[target objectAtIndex:1] shortValue];
//    short data3 = [[target objectAtIndex:5] shortValue];
//    short hbr = [[vhECGStressTempLib shared] getMeanHRWithData1:data1 data2:data2 data3:data3];
//    if (hbr <= 0) return;
//    if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:heartBeatRate:)]) {
//        [self.delegate icvBleManager:self heartBeatRate:hbr];
//    }
    //获取心率
    short hbr = [[vhECGFiltersLib shared] meanHRLibWithData:target];
    if (hbr > 0) {
        if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:heartBeatRate:)]) {
            [self.delegate icvBleManager:self heartBeatRate:hbr];
        }
    }
//    //获取rrms
//    short rrms = [[vhECGFiltersLib shared] meanRRmsLibWithData:target];
//    if (rrms > 0) {
//        if (self.delegate && [self.delegate respondsToSelector:@selector(icvBleManager:rrIntervalMs:)]) {
//            [self.delegate icvBleManager:self rrIntervalMs:rrms];
//        }
//    }
}

-(NSNumber *)checkNumber:(NSNumber *)value {
    //short 数据指针的数值范围容错处理 开始
    if ([value intValue] < -32768){
        value = [NSNumber numberWithShort:-32768];
    }else if ([value intValue] > 32767){
        value = [NSNumber numberWithShort:32767];
    }
    return value;
}
@end
